#ifndef ATTENDANCEMANAGER_H
#define ATTENDANCEMANAGER_H

#include <QObject>

#include <QString>
#include <QSqlDatabase>
#include <QTime>
#include <QDate>
#include <QDateTime>


/**
 * @brief 打卡结果结构体
 */
struct ClockResult {
    bool success;           ///< 操作是否成功
    QString message;        ///< 返回消息
    QString clockType;      ///< "上班"、"下班"或"重复打卡"
    QDateTime clockTime;    ///< 打卡时间
};

/**
 * @brief 每日打卡设置结构体
 */
struct ClockingTime {
    QTime startTime;  ///< 上班打卡时间
    QTime endTime;    ///< 下班打卡时间
};

/**
 * @brief 考勤管理类
 *
 * 该类封装了基于 RFID 卡号的考勤打卡流程，并对流程进行了解耦。
 * 根据当前日期可以获取对应的打卡时间设置。
 */
class AttendanceManager : public QObject
{
    Q_OBJECT
public:
    /**
     * @brief 构造函数
     * @param db 已经打开的数据库连接
     */
    explicit AttendanceManager(QSqlDatabase &db, QObject *parent = nullptr);

    /**
     * @brief 执行打卡操作
     * @param rfidCard RFID 卡号
     * @return 打卡结果
     */
    ClockResult clockInOut(const QString &rfidCard);

    /**
     * @brief 设置平日打卡设置
     * @param settings 平日上班与下班时间设置
     */
    void setWeekdaySettings(const ClockingTime &settings);
signals:
    /**
     * @brief 发出未注册的员工卡号
     * @param rfidCard 员工卡号
     */
    void employeeCard(const QString &rfidCard);
private:
    QSqlDatabase m_db;
    ClockingTime m_weekdaySettings;  ///< 平日打卡时间设置

    /**
     * @brief 获取当前日期字符串（格式：yyyy-MM-dd）
     */
    QString currentDate() const;

    /**
     * @brief 根据指定日期获取打卡设置
     * @param date 日期
     * @return 对应日期的打卡设置
     */
    ClockingTime getDailySettings(const QDate &date);

    /**
     * @brief 根据 RFID 卡号获取员工ID
     * @param rfidCard RFID 卡号
     * @param empId 返回的员工ID
     * @return true 成功查询到员工ID；false 则表示员工不存在或查询失败
     */
    bool getEmployeeId(const QString &rfidCard, int &empId);

    /**
     * @brief 获取当天考勤记录
     *
     * 查询指定员工在当前日期是否已有考勤记录。
     *
     * @param empId 员工ID
     * @param attId 返回的考勤记录ID（若存在）
     * @param hasRecord 返回当天是否存在考勤记录
     * @param clockOut 返回的下班打卡时间字段（可能为 NULL）
     * @return true 查询成功；false 则表示查询失败
     */
    bool getTodayAttendanceRecord(int empId, int &attId, bool &hasRecord, QVariant &clockOut);

    /**
     * @brief 执行上班打卡（插入记录）
     * @param empId 员工ID
     * @param settings 对应日期的打卡设置
     * @param clockTime 打卡时间
     * @param newAttId 返回新插入记录的ID
     * @return true 上班打卡成功；false 则表示操作失败
     */
    bool punchIn(int empId, const ClockingTime &settings, const QDateTime &clockTime, int &newAttId);

    /**
     * @brief 执行下班打卡（更新记录）
     * @param attId 考勤记录ID
     * @param settings 对应日期的打卡设置
     * @param clockTime 打卡时间
     * @return true 下班打卡成功；false 则表示操作失败
     */
    bool punchOut(int attId, const ClockingTime &settings, const QDateTime &clockTime);

};

#endif // ATTENDANCEMANAGER_H
